home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / std / c++ / 679 < prev    next >
Encoding:
Text File  |  1996-08-06  |  7.0 KB  |  159 lines

  1. Path: chronicle.mti.sgi.com!austern
  2. From: David Held <dheld@turing.cs.stcloud.msus.edu>
  3. Newsgroups: comp.std.c++
  4. Subject: Question about file-scope constants...
  5. Date: 10 Mar 1996 16:38:22 PST
  6. Organization: Minnesota State Universities
  7. Approved: austern@isolde.mti.sgi.com
  8. Message-ID: <314100A9.41C6@turing.cs.stcloud.msus.edu>
  9. NNTP-Posting-Host: isolde.mti.sgi.com
  10. X-Original-Date: Fri, 08 Mar 1996 19:53:13 -0800
  11. X-Mailer: Mozilla 2.0 (X11; I; IRIX 5.3 IP22)
  12. X-Auth: PGPMoose V1.1 PGP comp.std.c++
  13.     iQBVAwUBMUN2DUy4NqrwXLNJAQFbTgH9ETx8B0WjlOafcuc8NQoxtq+dARG92may
  14.     374ixZX9qUzHI9KAb8R/m/EqefrYkMNHtotlEhc7q1yeKNVEXS7H/A==
  15.     =hOn6
  16. Originator: austern@isolde.mti.sgi.com
  17.  
  18. I was under the impression that a const object of any type and its data
  19. members remained constant throughout their scope (which should be the
  20. whole file, in this case), and that those data members were correctly
  21. accessible from within any function in that scope.  After seeing how
  22. long my post was, I thought I had better get to the point darned quickly
  23. at the beginning. ;>
  24.     I'm using g++ 2.7.2 on a Linux box (which I suppose shouldn't be
  25. important in comp.std.c++, but I thought I'd include it in case someone
  26. knows of an anomaly), and I'm trying to cobble a little exception class
  27. together.  It's really simple, so I'll include some of the declarations
  28. here:
  29.  
  30. const int Name_Size = 65;
  31.  
  32. class Exception
  33. {
  34. protected:
  35.  
  36.   char the_Name[Name_Size];
  37.   static Node *the_List;
  38.  
  39. public:
  40.  
  41.   Exception(char *);
  42.   Exception(const Exception &);
  43.  
  44.   bool operator ==(const Exception &) const;
  45.   bool operator !=(const Exception &) const;
  46.  
  47.   void Raise(char * = NULL) const;
  48.  
  49.   static void Entry(char *);
  50.   static void Exit(char *);
  51.  
  52. };
  53.  
  54. Now the idea is that for every function, I call Exception::Entry with a
  55. little message giving the name of the function I have entered.  The
  56. Entry function appends a new Node to the end of a linked list pointed to
  57. by the_List.  This Node contains the name in a static size string
  58. (char[65]).  When I encounter a case where I want to raise an exception,
  59. I call Raise with a little message stating the circumstances of the
  60. Exception.  Here's an exampe:
  61.  
  62. const Exception Memory_Error("Memory Error");
  63.  
  64. if (!(data = new int[64])) {
  65.  
  66.   Memory_Error.Raise("Failed memory allocation.");
  67.  
  68. }
  69.  
  70. The Raise function goes down the_List, printing the function name in
  71. each Node until it reaches the end.  It then prints the handy-dandy
  72. message, and throws itself (throw(*this)).  If there is an Exception
  73. catcher nearby, the Exception can be handled.  Otherwise, it terminates
  74. the program.  The purpose of my class is to make it easy to debug
  75. programs by locating the exact point where an exception occurs without
  76. stepping through with a debugger.  I can follow the function trail down
  77. the place where the exception was raised. Here's a typical output:
  78.  
  79. Cursor out of bounds.
  80. Demo:
  81. Show_Menu():
  82. Move_Cursor():
  83. Exception Boundary Error was raised.
  84.  
  85. Here's my problem: I declare several const Exceptions in the exception.h
  86. file, since they are ones that I expect to use in every program
  87. (Memory_Error, Boundary_Error, File_Error, etc.).  Since I have to
  88. #include "exception.h" in a file to use the exceptions anyway, it makes
  89. sense.  I wrote a demo program where the main body is in a file called
  90. main.cpp, and the exception testing demo is in exception_demo.cpp.  I
  91. have appropriate header files for both, and I include exception.h in
  92. both (I set a meta-variable to make sure exception.h only gets included
  93. once).  Exception_demo.cpp contains the testing function, but apparently
  94. when the program enters this only function of exception_demo.cpp, one of
  95. the exceptions declared in exception.h gets mysteriously modified.  This
  96. is weird, because they are const.  So, in exception.h, I have some const
  97. Exceptions declared thusly:
  98.  
  99. const Exception
  100.   No_Exception("No Exception"),
  101.   Boundary_Error("Boundary Error"),
  102.   Memory_Error("Memory Error"),
  103.   File_Error("File Error");
  104.  
  105. When I go to raise No_Exception (i.e.: No_Exception.Raise("Testing");),
  106. the_Name is wrong.  That is, No_Exception.the_Name is not "No
  107. Exception", like it is supposed to be.  Instead, it is " Error\000ption"
  108. followed by 52 ASCII 0's.  At first, I had the_Name allocated
  109. dynamically, inside the Exception constructor, but when I got this
  110. problem, I changed it to static strings.  The problem persisted (I
  111. thought maybe it had something to do with destructors being called or
  112. not having a copy constructor), so now I'm stumped.
  113.     I was under the impression that if you declare a const object of file
  114. scope, with only statically allocated data members, that all of its data
  115. would remain intact within that scope, and that the object would be
  116. visible in any function entered within that scope.  Apparently, someone
  117. is tampering with my data, and it appears that they are breaking the
  118. rules.  There are no assignments to Exception::the_Name after the
  119. constructor is called.  There is no conceivable way that my code could
  120. be modifying the object data.
  121.     There are a few interesting phenomena to note: the first const
  122. Exception is the only one that gets tampered with.  All of the rest of
  123. them remain the same.  I have juggled them around, changed their names,
  124. everything I could think of.  The first one is always the only one that
  125. changes.  When I traced through the code with gdb, No_Exception (which I
  126. used to use when I was passing Exceptions back through functions,
  127. instead of throwing them--didn't have 2.7.2) is fine all the way to the
  128. point where exception_demo.cpp is entered, and void Exception_Demo(void)
  129. is called (all that happens up to then, is you can pick which demo you
  130. want to run through a primitive text menu--no possible interference
  131. here).  During the call to exception_demo.cpp is when
  132. No_Exception.the_Name gets corrupted.  I know this, because I
  133. single-stepped through the code, and inspected No_Exception.the_Name
  134. both before the call, and after the first line of Exception_Demo(void)
  135. (which happens to be an innocent cout statement).  The name appears to
  136. get corrupted during the call.  However, I believe that it is "magically
  137. restored" back in main.cpp.  This indicates to me that some foul copy of
  138. No_Exception is used in exception_demo.cpp (and thus Exception_Demo()).
  139. Is this true?  I have a correct copy constructor defined, so I would
  140. think that even if it made a temporary, that it would do so correctly
  141. (after all, all the other exceptions work fine).
  142.     In summary, I was under the impression that a const object of any type
  143. and its data members remained constant throughout their scope (which
  144. should be the whole file, in this case), and that those data members
  145. were correctly accessible from within any function in that scope.  If
  146. anyone can help me, or clarify the defined actions of C++, I would
  147. greatly appreciate it.
  148.  
  149.             Sincerely,
  150.  
  151.             Dave Held.
  152. ---
  153. [ comp.std.c++ is moderated.  To submit articles: Try just posting with your 
  154.                 newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  155.   comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  156.   Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  157.   Comments? mailto:std-c++-request@ncar.ucar.edu 
  158. ]
  159.